package my.graduation.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.Claims;
import my.graduation.constant.JwtClaimsConstant;
import my.graduation.dto.AdminInfoDto;
import my.graduation.dto.EmployeeLoginDto;
import my.graduation.dto.EmployeeLogoutDto;
import my.graduation.dto.RepassDto;
import my.graduation.entity.Administrator;
import my.graduation.entity.Doctor;
import my.graduation.entity.Patient;
import my.graduation.enums.HttpCodeEnums;
import my.graduation.mapper.AdminMapper;
import my.graduation.properties.JwtProperties;
import my.graduation.result.Result;
import my.graduation.service.AdminService;
import my.graduation.util.JwtUtil;
import my.graduation.vo.AdminLoginVO;
import my.graduation.vo.AdminVO;
import my.graduation.vo.PatientVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author: RavenLyn
 * @Date: 2024-11-27
 */

@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Administrator> implements AdminService {

    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 管理员登录
     * @param dto
     * @return
     */
    @Override
    public Result<AdminLoginVO> login(EmployeeLoginDto dto) {
        // 1 正常登录  用户名和密码
        // 用户名和密码都非空
        if(StringUtils.isNotBlank(dto.getUsername()) &&
                StringUtils.isNotBlank(dto.getPassword())){
            // 1.1 根据用户名查询用户信息
            Administrator admin = getOne(Wrappers.<Administrator>lambdaQuery().eq(Administrator::getUsername, dto.getUsername()));
            if(admin == null){
                return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
            }
            // 1.2 比对密码  MD5加密
            String pswd = DigestUtils.md5DigestAsHex(dto.getPassword().getBytes());
//            System.out.println(pswd);
            if(!pswd.equals(admin.getPassword())){
                return Result.error(HttpCodeEnums.LOGIN_PASSWORD_ERROR);
            }
            // 1.3 返回数据  admin+token
            Map<String,Object> claims = new HashMap<>();
            claims.put(JwtClaimsConstant.ADMIN_ID, admin.getId());
            String token = JwtUtil.createJWT(
                    jwtProperties.getAdminSecretKey(),
                    jwtProperties.getAdminTtl(),
                    claims);
            AdminLoginVO adminLoginVO = new AdminLoginVO();
            BeanUtils.copyProperties(admin,adminLoginVO);
            adminLoginVO.setUserName(admin.getUsername());
            adminLoginVO.setToken(token);
            return Result.success(adminLoginVO);
        }else{
            return Result.error(HttpCodeEnums.LOGIN_IS_BLANK);
        }
    }

    /**
     * 管理员登出
     * @param dto
     * @return
     */
    @Override
    public Result logout(EmployeeLogoutDto dto) {
        if(StringUtils.isNotBlank(dto.getToken())){
            String token = dto.getToken();
            Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(),token);
            Date exp = claims.getExpiration();
            long expMillis = exp.getTime() / 1000;
            long currentTimeSeconds = System.currentTimeMillis() / 1000;

            if (expMillis < currentTimeSeconds) { // token已过期
                return Result.error(HttpCodeEnums.INVALID_TOKEN_OR_EXPIRED);
            }
            redisTemplate.opsForValue().set(token, null, (expMillis - currentTimeSeconds), TimeUnit.SECONDS);
            return Result.success();
        }else {
            return Result.error(HttpCodeEnums.INVALID_TOKEN_OR_EXPIRED);
        }
    }

    /**
     * 获取管理员信息
     * @return
     */
    @Override
    public Result<List<AdminVO>> getList() {
        List<Administrator> adminList = list();

        return getListMethod(adminList);
    }

    /**
     * 条件获取管理员信息
     * @param dto
     * @return
     */
    @Override
    public Result<List<AdminVO>> getListByCon(AdminInfoDto dto) {
        List<Administrator> adminList = list(Wrappers.<Administrator>lambdaQuery()
                .like(Administrator::getName, dto.getName()));

        return getListMethod(adminList);
    }

    /**
     * 获取管理员信息封装method
     * @param adminList
     * @return
     */
    public Result<List<AdminVO>> getListMethod(List<Administrator> adminList){
        List<AdminVO> adminVOList = new ArrayList<>();
        for(Administrator admin : adminList){
            AdminVO adminVO = new AdminVO();
            BeanUtils.copyProperties(admin,adminVO);
            adminVOList.add(adminVO);
        }

        return Result.success(adminVOList);
    }


    /**
     * 新增管理员信息
     * @return
     */
    @Override
    public Result add(AdminInfoDto dto) {
        // 1 先校验用户名是否已存在
        List<Administrator> adminList = list(Wrappers.<Administrator>lambdaQuery().eq(Administrator::getUsername, dto.getUsername()));
        if(!adminList.isEmpty()){
            return Result.error(HttpCodeEnums.USERNAME_EXIST);
        }
        // 2 非空字段校验
        if(StringUtils.isNotBlank(dto.getName()) &&
                StringUtils.isNotBlank(dto.getPhone()) &&
                dto.getGender() != null &&
                dto.getUsername() != null){

            Administrator admin = new Administrator();
            BeanUtils.copyProperties(dto,admin);
            // 3 初始化密码
            admin.setPassword(DigestUtils.md5DigestAsHex(("12345").getBytes()));
            boolean i = save(admin);
            if (i) {
                return Result.success();
            } else {
                return Result.error(HttpCodeEnums.SYSTEM_ERROR);
            }
        }else {
            return Result.error(HttpCodeEnums.INFO_IS_BLANK);
        }
    }

    /**
     * 修改管理员信息
     * @return
     */
    @Override
    public Result update(AdminInfoDto dto) {
        // 1 非空字段校验
        if(dto.getId() != null){
            Administrator admin = new Administrator();
            BeanUtils.copyProperties(dto,admin);
            boolean i = updateById(admin);
            if (i) {
                return Result.success();
            } else {
                return Result.error(HttpCodeEnums.SYSTEM_ERROR);
            }
        }else {
            return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
        }
    }

    /**
     * 删除管理员信息
     * @return
     */
    @Override
    public Result delete(AdminInfoDto dto) {
        // 1 非空字段校验
        if(dto.getId() != null){
            Administrator admin = new Administrator();
            BeanUtils.copyProperties(dto,admin);
            boolean i = removeById(admin);
            if (i) {
                return Result.success();
            } else {
                return Result.error(HttpCodeEnums.SYSTEM_ERROR);
            }
        }else {
            return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
        }
    }

    /**
     * 管理员获取个人信息
     * @param dto
     * @return
     */
    @Override
    public Result<AdminVO> getPersonal(AdminInfoDto dto) {
        if(dto.getId() != null){
            Administrator one = getOne(Wrappers.<Administrator>lambdaQuery().eq(Administrator::getId, dto.getId()));
            AdminVO adminVO = new AdminVO();
            BeanUtils.copyProperties(one,adminVO);
            return Result.success(adminVO);
        }else {
            return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
        }
    }

    /**
     * 管理员修改密码
     * @param dto
     * @return
     */
    @Override
    public Result repass(RepassDto dto) {
        if(dto.getId() != null &&
                dto.getNewPass() != null &&
                dto.getOldPass() != null){
            Administrator one = getOne(Wrappers.<Administrator>lambdaQuery()
                    .eq(Administrator::getId, dto.getId()));
            String oldPswd = DigestUtils.md5DigestAsHex(dto.getOldPass().getBytes());

            if(oldPswd.equals(one.getPassword())){ //旧密码匹配成功
                String newPswd = DigestUtils.md5DigestAsHex(dto.getNewPass().getBytes());
                update(Wrappers.<Administrator>lambdaUpdate()
                        .eq(Administrator::getId,dto.getId())
                        .set(Administrator::getPassword,newPswd));
                return Result.success();
            }else {
                return Result.error(HttpCodeEnums.OLD_PASSWORD_WRONG);
            }
        }else {
            return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
        }
    }
}
